home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
asmutil
/
68kdis.zip
/
PRIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1988-12-03
|
6KB
|
335 lines
/*
* SCCS: @(#)prin.c 1.2 11/2/84 14:19:47
* Print stuff.
*
***********************************************************************
* This software is copyright of
*
* John M Collins
* 47 Cedarwood Drive
* St Albans
* Herts, AL4 0DN
* England +44 727 57267
*
* and is released into the public domain on the following conditions:
*
* 1. No free maintenance will be guaranteed.
* 2. Nothing may be based on this software without
* acknowledgement, including incorporation of this
* notice.
*
* Notwithstanding the above, the author welcomes correspondence and bug
* fixes.
***********************************************************************
*/
#include <stdio.h>
#include <a.out.h>
#include <ldfcn.h>
#include "unc.h"
#define LINELNG 70
void gette(), getde();
long gettw(), getdw();
void prinst();
char noabs; /* No non-global absolutes */
int rel; /* File being analysed is relocatable */
int lpos;
struct commit abstab, comtab;
extern char shlibout;
/*
* Print absolute and common values.
*/
void pabs()
{
register int i;
register symbol cs;
for (i = 0; i < abstab.c_int; i++)
for (i = 0; i < abstab.c_int; i++) {
cs = abstab.c_symb[i];
if (cs->s_value >= 0x300000 && ! shlibout)
continue;
if (cs->s_glob)
(void) printf("#\tglobal\t%s\n", cs->s_name);
else if (noabs)
continue;
(void) printf("# %s\t= 0x%lx\n", cs->s_name, cs->s_value);
}
for (i = 0; i < comtab.c_int; i++) {
cs = comtab.c_symb[i];
(void) printf("\tcomm\t%s,%d\n", cs->s_name, cs->s_value);
}
}
/*
* Print out labels.
*/
void plabs(ls, seg)
register symbol ls;
int seg;
{
for (; ls != NULL; ls = ls->s_link) {
if (ls->s_type != seg)
continue;
if (ls->s_lsymb) {
(void) printf("L%%%u:\n", ls->s_lsymb);
return; /* Set last */
}
if (ls->s_glob)
(void) printf("\n\tglobal\t%s", ls->s_name);
if (ls->s_name[0] == '.')
(void) printf("\n# %s:\n", ls->s_name);
else
(void) printf("\n%s:\n", ls->s_name);
}
}
/*
* Print out text.
*/
void ptext(fid)
register ef_fid fid;
{
register long tpos, endt;
t_entry tstr;
(void) fputs("\ttext\n", stdout);
tpos = fid->ef_tbase;
endt = tpos + fid->ef_tsize;
contin:
for (; tpos < endt; tpos += tstr.t_lng * 2) {
gette(fid, tpos, &tstr);
plabs(tstr.t_lab, S_TEXT);
if (tstr.t_type == T_BEGIN)
prinst(&tstr, tpos);
else if (tstr.t_relsymb != NULL) {
(void) printf("\tlong\t%s", tstr.t_relsymb->s_name);
if (tstr.t_relsymb->s_type!=S_TEXT &&
tstr.t_relsymb->s_type!=S_DATA)
(void) printf("+0x%x", gettw(fid, tpos, R_LONG));
(void) putchar('\n');
tpos += 4;
goto contin;
}
else
(void) printf("\tshort\t0x%x\n", tstr.t_contents);
}
/*
* Print out any trailing label.
*/
gette(fid, tpos, &tstr);
plabs(tstr.t_lab, S_TEXT);
}
/*
* Print out data.
*/
void pdata(fid)
register ef_fid fid;
{
register long dpos, endd;
register int lng, ccnt;
unsigned ctyp;
int had, par, inc;
char *msg;
d_entry dstr;
(void) fputs("\n\tdata\n", stdout);
dpos = fid->ef_dbase;
endd = dpos + fid->ef_dsize;
while (dpos < endd) {
getde(fid, dpos, &dstr);
plabs(dstr.d_lab, S_DATA);
switch (dstr.d_type) {
case D_CONT:
(void) fprintf(stderr, "Data sync error\n");
dpos++;
break;
case D_ASC:
case D_ASCZ:
ctyp = dstr.d_type;
lng = dstr.d_lng;
nextline:
(void) fputs("\tbyte\t", stdout);
ccnt=0;
while (lng > 0) {
if (ccnt) (void) putchar(',');
getde(fid, dpos, &dstr);
switch (dstr.d_contents) {
default:
if (dstr.d_contents < ' ' ||
dstr.d_contents > '~')
ccnt += printf("0x%x", dstr.d_contents);
else {
(void) putchar('\'');
(void)putchar(dstr.d_contents);
ccnt += 2;
}
break;
case '\\':
(void) putchar('\'');
(void) putchar('\\');
(void) putchar('\\');
ccnt+=2;
break;
case '\b':
(void) putchar('\'');
(void) putchar('\\');
(void) putchar('b');
ccnt+=2;
break;
case '\n':
(void) putchar('\'');
(void) putchar('\\');
(void) putchar('n');
ccnt+=2;
break;
case '\r':
(void) putchar('\'');
(void) putchar('\\');
(void) putchar('r');
ccnt+=2;
break;
case '\f':
(void) putchar('\'');
(void) putchar('\\');
(void) putchar('f');
ccnt+=2;
break;
case '\t':
(void) putchar('\'');
(void) putchar('\\');
(void) putchar('t');
ccnt+=2;
break;
}
lng--;
dpos++;
if (++ccnt > 40 && lng > 0) {
(void) putchar('\n');
goto nextline;
}
}
(void) putchar('\n');
break;
case D_BYTE:
msg = "byte";
par = R_BYTE;
inc = 1;
goto wrest;
case D_WORD:
msg = "short";
par = R_WORD;
inc = 2;
goto wrest;
case D_LONG:
msg = "long";
par = R_LONG;
inc = 4;
wrest:
(void) putchar('\t');
(void) fputs(msg, stdout);
(void) putchar('\t');
lng = dstr.d_lng;
lpos = 16;
had = 0;
while (lng > 0) {
if (lpos > LINELNG) {
(void) putchar('\n');
(void) putchar('\t');
(void) fputs(msg, stdout);
(void) putchar('\t');
lpos = 16;
}
else if (had) {
(void) putchar(',');
(void) putchar(' ');
lpos += 2;
}
lpos += printf("0x%x", getdw(fid, dpos, par));
lng -= inc;
dpos += inc;
had++;
}
(void) putchar('\n');
break;
case D_ADDR:
(void) fputs("\tlong\t", stdout);
lng = dstr.d_lng;
lpos = 16;
had = 0;
while (lng > 0) {
if (lpos > LINELNG) {
(void) fputs("\n\tlong\t", stdout);
lpos = 16;
}
else if (had) {
(void) putchar(',');
(void) putchar(' ');
lpos += 2;
}
getde(fid, dpos, &dstr);
lpos += printf("%s", dstr.d_relsymb->s_name);
lng -= sizeof(long);
dpos += sizeof(long);
had++;
}
(void) putchar('\n');
break;
}
}
/*
* Print trailing label.
*/
getde(fid, dpos, &dstr);
plabs(dstr.d_lab, S_DATA);
}
void pbss(fid)
register ef_fid fid;
{
register long bpos = fid->ef_bbase;
long endb = fid->ef_end;
d_entry bstr;
(void) fputs("\n# .bss\n", stdout);
while (bpos < endb) {
getde(fid, bpos, &bstr);
plabs(bstr.d_lab, S_BSS);
(void) printf("\tspace\t%d\n", bstr.d_lng);
bpos += bstr.d_lng;
}
getde(fid, endb, &bstr);
plabs(bstr.d_lab, S_BSS);
}